{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "64fa991c-98e5-4be0-a838-06a4617d8be3",
   "metadata": {},
   "source": [
    "## Part 4: Adding external data \n",
    "In addition to short term, in-context memories, Letta agents also have a long term memory store called *archival memory*. We can enable agents to leverage external data (e.g. PDF files, database records, etc.) by inserting data into archival memory. In this example, we'll show how to load the Letta paper a *source*, which defines a set of data that can be attached to agents. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c61ac9c3-cbea-47a5-a6a4-4133ffe5984e",
   "metadata": {},
   "source": [
    "We first download a PDF file, the Letta paper: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f89e9156-3d2d-4ce6-b5e9-aeb4cdfd5657",
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "\n",
    "url = \"https://arxiv.org/pdf/2310.08560\"\n",
    "response = requests.get(url)\n",
    "filename = \"letta_paper.pdf\"\n",
    "\n",
    "with open(filename, 'wb') as f:\n",
    "    f.write(response.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bcfe3a48-cdb0-4843-9599-623753eb61b9",
   "metadata": {},
   "source": [
    "Next, we create a Letta source to load data into: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7ccf21fb-5862-42c2-96ca-63e0ba2f48b5",
   "metadata": {},
   "outputs": [],
   "source": [
    "letta_paper = client.sources.create(\n",
    "    name=\"letta_paper\", \n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f114bf0b-6a25-4dbf-9c2c-59271d46ebba",
   "metadata": {},
   "source": [
    "Now that we have a source, we can load files into the source. Loading the file will take a bit of time, since the file needs to be parsed and stored as *embeddings* using an embedding model. The loading function returns a *job* which can be pinged for a status. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6fe624eb-bf08-4267-a849-06103c1ad5b6",
   "metadata": {},
   "outputs": [],
   "source": [
    "job = client.sources.files.upload(filename=filename, source_id=letta_paper.id)\n",
    "job"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27ce13f5-d878-406d-9a5f-7e2335f2ef0d",
   "metadata": {},
   "source": [
    "### Attaching data to an agent \n",
    "To allow an agent to access data in a source, we need to *attach* it to the agent. This will load the source's data into the agent's archival memory. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5be91571-87ee-411a-8e79-25c56c414360",
   "metadata": {},
   "outputs": [],
   "source": [
    "client.agents.sources.attach(source_id=letta_paper.id, agent_id=basic_agent.id)\n",
    "# TODO: add system message saying that file has been attached \n",
    "\n",
    "from pprint import pprint\n",
    "\n",
    "# TODO: do soemthing accenture related \n",
    "# TODO: brag about query rewriting -- hyde paper \n",
    "response = client.agents.messages.create(agent_id=basic_agent.id, messages=[\n",
    "    MessageCreate(\n",
    "        role=\"user\",\n",
    "        content=\"what is core memory? search your archival memory.\",\n",
    "    )\n",
    "])\n",
    "pprint(response.messages)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "letta",
   "language": "python",
   "name": "letta"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
